<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link href="../css/main.css" media="all" rel="stylesheet" type="text/css" />
<link href="../css/highlight.css" media="all" rel="stylesheet" type="text/css" />
<link href="../css/print.css" media="print" rel="stylesheet" type="text/css" />
<title>第4章 - ページの作り方の基本</title>
</head>

<body>
<div class="navigation">

<table width="100%">
<tr>
<td width="40%" align="left"><a href="03-Running-Symfony.html">前の章</a></td>
<td width="20%" align="center"><a href="index.html">ホーム</a></td>
<td width="40%" align="right"><a href="05-Configuring-Symfony.html">次の章</a></td>
</tr>
</table>
<hr/>
</div>

<div>
<a name="chapter.4.the.basics.of.page.creation" id="chapter.4.the.basics.of.page.creation"></a><h1>第4章 - ページの作り方の基本</h1>

<p>興味深いことに、プログラマが新しい言語もしくはフレームワークを学ぶとき、最初に学ぶチュートリアルは"Hello,world!"をスクリーン上に表示させることです。人工知能の分野におけるあらゆる試みが今のところ貧弱な会話能力の結果で終わっているので、コンピュータを世界全体に挨拶できる何かと考えるのは奇妙なことです。しかしながら、symfonyはほかのプログラムよりも愚かではないので、その証明として、symfonyで"Hello,<code>&lt;Your Name Here&gt;</code>"と表示するページを作ることができます。</p>

<p>この章ではモジュールの作り方をお教えします。モジュール(module)とはページを分類する構造上の要素です。MVCパターンなので、アクションとテンプレートに分割されたページを作る方法も学びます。リンクとフォームはWebの基本的なインタラクションです。これらをテンプレートに挿入してアクションで扱う方法を理解します。</p>

<div class="toc">
<dl>
<dt><a href="#creating.a.module.skeleton">4.1. モジュールのスケルトンを作成する</a></dt>
<dt><a href="#adding.a.page">4.2. ページを追加する</a></dt>
<dd><dl>
<dt><a href="#adding.an.action">4.2.1. アクションを追加する</a></dt>
<dt><a href="#adding.a.template">4.2.2. テンプレートを追加する</a></dt>
<dt><a href="#passing.information.from.the.action.to.the.template">4.2.3. テンプレートにアクションからの情報を渡す</a></dt>
</dl></dd>
<dt><a href="#gathering.information.from.the.user.with.forms">4.3. ユーザーからの情報をフォームで集める</a></dt>
<dt><a href="#linking.to.another.action">4.4. 別のアクションにリンクする</a></dt>
<dt><a href="#getting.information.from.the.request">4.5. リクエストから情報を入手する</a></dt>
<dt><a href="#summary">4.6. まとめ</a></dt>
</dl>
</div>
<a name="creating.a.module.skeleton" id="creating.a.module.skeleton"></a><h2>モジュールのスケルトンを作成する</h2>

<p>2章で説明したように、symfonyはページをモジュールに分類します。ページを作るまえに、モジュールを作成する必要があります。モジュールはsymfonyが認識できるファイル構造を持つ最初は内容を持たない骨組みです。</p>

<p>symfonyのコマンドラインはモジュールの作成作業を自動化します。アプリケーションの名前とモジュールの名前を引数として<code>init-module</code>タスクを呼び出す必要があるだけです。前の章で、<code>myapp</code>アプリケーションを作りました。<code>mymodule</code>モジュールをこの<code>myapp</code>アプリケーションに追加するために、つぎのコマンドを入力します:</p>

<pre><code>&gt; cd ~/myproject
&gt; symfony init-module myapp mymodule

&gt;&gt; dir+      ~/myproject/apps/myapp/modules/mymodule
&gt;&gt; dir+      ~/myproject/apps/myapp/modules/mymodule/actions
&gt;&gt; file+     ~/myproject/apps/myapp/modules/mymodule/actions/actions.class.php
&gt;&gt; dir+      ~/myproject/apps/myapp/modules/mymodule/config
&gt;&gt; dir+      ~/myproject/apps/myapp/modules/mymodule/lib
&gt;&gt; dir+      ~/myproject/apps/myapp/modules/mymodule/templates
&gt;&gt; file+     ~/myproject/apps/myapp/modules/mymodule/templates/indexSuccess.php
&gt;&gt; dir+      ~/myproject/apps/myapp/modules/mymodule/validate
&gt;&gt; file+     ~/myproject/test/functional/myapp/mymoduleActionsTest.php
&gt;&gt; tokens    ~/myproject/test/functional/myapp/mymoduleActionsTest.php
&gt;&gt; tokens    ~/myproject/apps/myapp/modules/mymodule/actions/actions.class.php
&gt;&gt; tokens    ~/myproject/apps/myapp/modules/mymodule/templates/indexSuccess.php
</code></pre>

<p><code>actions/</code>、<code>config/</code>、<code>lib/</code>、<code>templates/</code>と<code>validate/</code>ディレクトリは別にして、このコマンドは3つのファイルだけ作りました。<code>test/</code>フォルダー内部に存在するファイルはユニットテストに関係しますが、15章まで気にする必要はありません。<code>actions.class.php</code>(リスト4-1で示されている)は<code>default</code>モジュールの初期ページに転送(フォワード)します。<code>templates/indexSuccess.php</code>ファイルは空です。</p>

<p>リスト4-1 - 生成されたデフォルトのアクション(<code>actions/actions.class.php</code>)</p>

<pre class="php"><span class="kw2">&lt;?php</span>
&nbsp;
<span class="kw2">class</span> mymoduleActions <span class="kw2">extends</span> sfActions
<span class="br0">&#123;</span>
  <span class="kw2">public</span> <span class="kw2">function</span> executeIndex<span class="br0">&#40;</span><span class="br0">&#41;</span>
  <span class="br0">&#123;</span>
    <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">forward</span><span class="br0">&#40;</span><span class="st_h">'default'</span><span class="sy0">,</span> <span class="st_h">'module'</span><span class="br0">&#41;</span><span class="sy0">;</span>
  <span class="br0">&#125;</span>
<span class="br0">&#125;</span></pre>

<blockquote class="note"><p>
  実際の<code>actions.class.php</code>ファイルを見ると、多くのコメントを含めて、これら数行よりも多くのものが見つかります。なぜならsymfonyはあなたのプロジェクトのドキュメントを作るためにPHP形式のコメントを使い、phpDocumentor(<a href="http://www.phpdoc.org/">http://www.phpdoc.org/</a>)と互換性のあるそれぞれのクラスファイルを用意することを推奨しているからです。</p>
</blockquote>

<p>新しいそれぞれのモジュールに対して、symfonyはデフォルトの<code>index</code>アクションを作ります。これは<code>executeIndex</code>と呼ばれるアクションメソッドと<code>indexSuccess.php</code>と呼ばれるテンプレートファイルから構成されます。プレフィックスの<code>execute</code>とサフィックスの<code>Success</code>の意味は6章と7章で説明します。それまでの間はこの命名方法を規約として考えることにします。つぎのURLをブラウザーに入力することで対応するページ(図4-1で再現)を見ることができます:</p>

<pre><code>http://localhost/myapp_dev.php/mymodule/index
</code></pre>

<p>この章ではデフォルトの<code>index</code>アクションを使わないので、<code>actions.class.php</code>ファイルから<code>executeIndex()</code>メソッドを削除し、<code>templates/</code>ディレクトリから<code>indexSuccess.php</code>ファイルを削除できます。</p>

<blockquote class="note"><p>
  symfonyはコマンドライン以外にもモジュールを初期化するほかの方法を提供します。これらの1つはあなた自身でディレクトリを作ることです。多くの場合、アクションとモジュールのテンプレートは任意のテーブルのデータを操作するために作られます。テーブルからレコードを作成する、読みとる、更新する、削除するために必要なコードはしばしば同じなので、symfonyはこのコードを生成するためにscaffoldingと呼ばれるメカニズムを提供します。このテクニックに関するより詳細な情報は14章を参照してください。</p>
</blockquote>

<p>図4-1 - 生成されたデフォルトのindexページ</p>

<p><img src="images/F0401.jpg" alt="生成されたデフォルトのindexページ" title="生成されたデフォルトのindexページ" /></p>

<a name="adding.a.page" id="adding.a.page"></a><h2>ページを追加する</h2>

<p>symfonyにおいて、ページの背後にあるロジックはアクションに保存され、プレゼンテーションはテンプレートに保存されます。ロジックをともなわないページでも空のアクションを必要とします。</p>

<a name="adding.an.action" id="adding.an.action"></a><h3>アクションを追加する</h3>

<p>"Hello, world!"のページは<code>myAction</code>アクションを通してアクセスできます。リスト4-2で示されているように、このアクションを作成するには、<code>executeMyAction</code>メソッドを<code>mymoduleActions</code>クラスに追加します。</p>

<p>リスト4-2 - アクションの追加は実行メソッドをアクションクラスに追加することと似ている(<code>actions/actions.class.php</code>)</p>

<pre class="php"><span class="kw2">&lt;?php</span>
&nbsp;
<span class="kw2">class</span> mymoduleActions <span class="kw2">extends</span> sfActions
<span class="br0">&#123;</span>
  <span class="kw2">public</span> <span class="kw2">function</span> executeMyAction<span class="br0">&#40;</span><span class="br0">&#41;</span>
  <span class="br0">&#123;</span>
  <span class="br0">&#125;</span>
<span class="br0">&#125;</span></pre>

<p>アクションのメソッド名はつねに<code>execute``Xxx``()</code>で、名前の2番目の部分は最初が大文字であるアクションの名前です。</p>

<p>では、つぎのURLをリクエストしてください:</p>

<pre><code>http://localhost/myapp_dev.php/mymodule/myAction
</code></pre>

<p><code>myActionSuccess.php</code>テンプレートが見つからないことをsymfonyが訴えます。これは正常なことです; symfonyにおいて、ページはつねにアクションとテンプレートで構成されます。</p>

<blockquote class="caution"><p>
  URL(ドメイン名ではありません)と同じように、symfonyは大文字と小文字を区別します(PHPはメソッド名の大文字と小文字を区別しません)。このことは<code>executemyaction()</code>メソッドもしくは<code>executeMyaction()</code>メソッドを追加してブラウザーで<code>myAction</code>を呼び出すと、symfonyが404エラーを返すことを意味します。</p>
</blockquote>

<p>-</p>

<blockquote class="sidebar"><p class="title">
  URLはレスポンスの一部</p>
  
  <p>symfonyは実際のアクションの名前とアクションを呼び出すために必要なURLの形式を完全に分離できるようにするルーティングシステムを持ちます。このメカニズムによってURLをあたかもレスポンスの一部のようにカスタム形式に整えることができます。もはやファイル構造やリクエストパラメーターによって制限されることはありません; アクションのためのURLを望むフレーズで表示できます。たとえば、通常、articleという名前のモジュールのindexアクションへの呼び出しはつぎのようになります:</p>

<pre><code>http://localhost/myapp_dev.php/article/index?id=123
</code></pre>
  
  <p>このURLはデータベースから任意の記事をとり出します。この例では、ヨーロッパのセクションのとりわけフランスのファイナンスについて議論している記事(<code>id=123</code>)がとり出されます。しかしながら、<code>routing.yml</code>設定ファイルを少し変更することでURLを完全に異なる形式で書けます:</p>

<pre><code>http://localhost/articles/europe/france/finance.html
</code></pre>
  
  <p>検索エンジンにわかりやすいURLになるだけでなく、ユーザーにとっても重要です。ユーザーは、カスタムクエリを行うために、つぎのようにアドレスバーを擬似コマンドラインとして使えます:</p>

<pre><code>http://localhost/articles/tagged/finance+france+euro
</code></pre>
  
  <p>symfonyはユーザーのためにスマートURLを解析し生成する方法を知っています。ルーティングシステムは自動的にスマートURLからリクエストパラメーターをはがし、アクションがこれらを利用できるようにします。レスポンスに含まれるハイパーリンクの形式を整えるので、これらは"スマート"に見えます。この機能について9章で詳しく学ぶことになります。</p>
  
  <p>全体的に、このことはあなたのアプリケーションのアクションを命名する方法は、アクションを呼び出すために使われるURLの見た目ではなく、アプリケーションのアクションの機能によって影響されることを意味します。アクションの名前はアクションが実際に行うことを説明し、不定詞の動詞(<code>show</code>、<code>list</code>、<code>edit</code>など)であることがよくあります。アクションの名前は全体的にエンドユーザーに対して見えないので、明確な名前(<code>listByName</code>もしくは<code>showWithComments</code>など)を使うことを躊躇しないでください。アクションの機能を説明するコードのコメントを書かずにすむことに加えて、コードがはるかに読みやすくなります。</p>
</blockquote>

<a name="adding.a.template" id="adding.a.template"></a><h3>テンプレートを追加する</h3>

<p>アクションはそれ自身をレンダリングすることをテンプレートに求めます。テンプレートはモジュールの<code>templates/</code>ディレクトリに設置されたファイルで、アクションとアクションのサフィックスで命名されます。アクションのデフォルトの接尾辞は"success"なので、<code>myAction</code>アクションのために作られるテンプレートファイルは<code>myActionSuccess.php</code>という名前になります。</p>

<p>テンプレートはプレゼンテーション用のコードだけを含むことを前提としているので、これらをできるかぎり小さなPHPコードとして維持してください。当然のことながら、"Hello, world!"を表示するページはリスト4-3のようなシンプルなテンプレートを持つことができます。</p>

<p>リスト4-3 - テンプレート(<code>mymodule/templates/myActionSuccess.php</code>)</p>

<pre class="php"><span class="sy0">&lt;</span>p<span class="sy0">&gt;</span>Hello<span class="sy0">,</span> world<span class="sy0">!&lt;/</span>p<span class="sy0">&gt;</span></pre>

<p>テンプレートのなかでPHPコードを実行する必要がある場合、リスト4-4で示すように、通常のPHP構文は避けるべきです。代わりに、PHPプログラマではない人でも理解できるように、リスト4-5で示されるPHPの代替構文を使うテンプレートを書きます。最終的なコードを正しくインデントするだけでなく、アクションの複雑なPHPコードを維持するための助けになります。なぜなら制御文(<code>if</code>、<code>foreach</code>、<code>while</code>など)だけが代替構文を持つからです。</p>

<p>リスト4-4 - アクションの用途にはよいが、テンプレートの用途にはよくない通常のPHP構文(<code>templates/showSuccess.php</code>)</p>

<pre class="php">&lt;p&gt;Hello, world!&lt;/p&gt;
<span class="kw2">&lt;?php</span>
&nbsp;
<span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$test</span><span class="br0">&#41;</span>
<span class="br0">&#123;</span>
  <span class="kw1">echo</span> <span class="st0">&quot;&lt;p&gt;&quot;</span><span class="sy0">.</span><span class="kw3">time</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">.</span><span class="st0">&quot;&lt;/p&gt;&quot;</span><span class="sy0">;</span>
<span class="br0">&#125;</span>
&nbsp;
<span class="sy1">?&gt;</span></pre>

<p>リスト4-5 - テンプレート用のPHPの代替構文のよい例(<code>templates/showSuccess.php</code>)</p>

<pre class="php">&lt;p&gt;Hello, world!&lt;/p&gt;
<span class="kw2">&lt;?php</span> <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$test</span><span class="br0">&#41;</span><span class="sy0">:</span> <span class="sy1">?&gt;</span>
&lt;p&gt;<span class="kw2">&lt;?php</span> <span class="kw1">echo</span> <span class="kw3">time</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="sy1">?&gt;</span>&lt;/p&gt;
<span class="kw2">&lt;?php</span> <span class="kw1">endif</span><span class="sy0">;</span> <span class="sy1">?&gt;</span></pre>

<blockquote class="tip"><p>
  テンプレートの構文が十分に読みやすいものか確認するためのよい経験則はPHPもしくは波かっこでechoされるHTMLコードを含まないことです。また多くの場合、<code>&lt;?php</code>で展開するとき、同じ行の<code>?&gt;</code>で閉じることです。</p>
</blockquote>

<a name="passing.information.from.the.action.to.the.template" id="passing.information.from.the.action.to.the.template"></a><h3>テンプレートにアクションからの情報を渡す</h3>

<p>アクションの仕事はすべての複雑な計算、データのとり出し、とテストの実施、echoもしくはテストされるテンプレートに対して変数を設定することです。symfonyは(アクションの<code>$this-&gt;variableName</code>経由でアクセスされる)アクションクラスの属性が(<code>$variableName</code>経由で)グローバルな名前空間内のテンプレートに直接アクセスできるようにします。リスト4-6と4-7はテンプレートにアクションからの情報を渡す方法を示しています。</p>

<p>リスト4-6 - テンプレートがアクションの属性を利用できるようにアクションを設定する(<code>mymodule/actions/actions.class.php</code>)</p>

<pre class="php"><span class="kw2">&lt;?php</span>
&nbsp;
<span class="kw2">class</span> mymoduleActions <span class="kw2">extends</span> sfActions
<span class="br0">&#123;</span>
  <span class="kw2">public</span> <span class="kw2">function</span> executeMyAction<span class="br0">&#40;</span><span class="br0">&#41;</span>
  <span class="br0">&#123;</span>
    <span class="re0">$today</span> <span class="sy0">=</span> <span class="kw3">getdate</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">hour</span> <span class="sy0">=</span> <span class="re0">$today</span><span class="br0">&#91;</span><span class="st_h">'hours'</span><span class="br0">&#93;</span><span class="sy0">;</span>
  <span class="br0">&#125;</span>
<span class="br0">&#125;</span></pre>

<p>リスト4-7 - テンプレートはアクションの属性に直接アクセスできる(<code>templates/showSuccess.php</code>)</p>

<pre class="php">&lt;p&gt;Hello, world!&lt;/p&gt;
<span class="kw2">&lt;?php</span> <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$hour</span> <span class="sy0">&gt;=</span> <span class="nu0">18</span><span class="br0">&#41;</span><span class="sy0">:</span> <span class="sy1">?&gt;</span>
&lt;p&gt;Or should I say good evening? It is already <span class="kw2">&lt;?php</span> <span class="kw1">echo</span> <span class="re0">$hour</span> <span class="sy1">?&gt;</span>.&lt;/p&gt;
<span class="kw2">&lt;?php</span> <span class="kw1">endif</span><span class="sy0">;</span> <span class="sy1">?&gt;</span></pre>

<blockquote class="note"><p>
  アクションの変数をセットアップしなくてもテンプレートはすでにごく一部のデータにアクセスできます。すべてのテンプレートは<code>$sf_context</code>、<code>$sf_request</code>、<code>$sf_params</code>、<code>$sf_user</code>オブジェクトのメソッドを呼び出すことができます。これらは現在のコンテキスト、リクエスト、リクエストパラメーター、セッションに関連するデータを含みます。まもなくこれらを効率的に使う方法を学ぶことになります。</p>
</blockquote>

<a name="gathering.information.from.the.user.with.forms" id="gathering.information.from.the.user.with.forms"></a><h2>ユーザーからの情報をフォームで集める</h2>

<p>フォームはユーザーから情報を得るためのよい方法です。HTMLのフォームとフォームの要素を書く作業は、とりわけXHTML準拠にしたい場合、やりづらいことがあります。リスト4-8で示されるように、通常の方法でフォームの要素をsymfonyのテンプレートに含めることができますが、symfonyはこのタスクをより簡単にするヘルパーを提供します。</p>

<p>リスト4-8 - 通常のHTMLコードをテンプレートに含めることができる</p>

<pre class="php">&lt;p&gt;こんにちは！&lt;/p&gt;
<span class="kw2">&lt;?php</span> <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$hour</span> <span class="sy0">&gt;=</span> <span class="nu0">18</span><span class="br0">&#41;</span><span class="sy0">:</span> <span class="sy1">?&gt;</span>
&lt;p&gt;それともこんばんはと言うほうがよろしいでしょうか？もう<span class="kw2">&lt;?php</span> <span class="kw1">echo</span> <span class="re0">$hour</span> <span class="sy1">?&gt;</span>時です。&lt;/p&gt;
<span class="kw2">&lt;?php</span> <span class="kw1">endif</span><span class="sy0">;</span> <span class="sy1">?&gt;</span>
&lt;form method=&quot;post&quot; action=&quot;/myapp_dev.php/mymodule/anotherAction&quot;&gt;
  &lt;label for=&quot;name&quot;&gt;お名前は？&lt;/label&gt;
  &lt;input type=&quot;text&quot; name=&quot;name&quot; id=&quot;name&quot; value=&quot;&quot; /&gt;
  &lt;input type=&quot;submit&quot; value=&quot;Ok&quot; /&gt;
&lt;/form&gt;</pre>

<p>ヘルパー(helper)とはsymfonyによって定義されたPHP関数で、テンプレートの範囲内で使われることを目的としています。ヘルパーはHTMLコードの出力を行いあなた自身でHTMLコードよりも速く書けます。symfonyのヘルパーを利用することで、リスト4-9で示されたコードがリスト4-8と同じ結果を得ることができます。</p>

<p>リスト4-9 - HTMLタグよりもヘルパーを利用したほうが速くて簡単</p>

<pre class="php">&lt;p&gt;こんにちは？&lt;/p&gt;
<span class="kw2">&lt;?php</span> <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$hour</span> <span class="sy0">&gt;=</span> <span class="nu0">18</span><span class="br0">&#41;</span><span class="sy0">:</span> <span class="sy1">?&gt;</span>
&lt;p&gt;それともこんばんはと言うほうがよろしいでしょうか？もう<span class="kw2">&lt;?php</span> <span class="kw1">echo</span> <span class="re0">$hour</span> <span class="sy1">?&gt;</span>時です。&lt;/p&gt;
<span class="kw2">&lt;?php</span> <span class="kw1">endif</span><span class="sy0">;</span> <span class="sy1">?&gt;</span>
<span class="kw2">&lt;?php</span> <span class="kw1">echo</span> form_tag<span class="br0">&#40;</span><span class="st_h">'mymodule/anotherAction'</span><span class="br0">&#41;</span> <span class="sy1">?&gt;</span>
  <span class="kw2">&lt;?php</span> <span class="kw1">echo</span> label_for<span class="br0">&#40;</span><span class="st_h">'name'</span><span class="sy0">,</span> <span class="st_h">'お名前は？'</span><span class="br0">&#41;</span> <span class="sy1">?&gt;</span>
  <span class="kw2">&lt;?php</span> <span class="kw1">echo</span> input_tag<span class="br0">&#40;</span><span class="st_h">'name'</span><span class="br0">&#41;</span> <span class="sy1">?&gt;</span>
  <span class="kw2">&lt;?php</span> <span class="kw1">echo</span> submit_tag<span class="br0">&#40;</span><span class="st_h">'Ok'</span><span class="br0">&#41;</span> <span class="sy1">?&gt;</span>
&lt;/form&gt;</pre>

<blockquote class="sidebar"><p class="title">
  ヘルパーはあなたをお助けします</p>
  
  <p>リスト4-9の例で、ヘルパー版のコードを書くほうがHTMLコードを直接書くよりも本当に速くないと思うのであれば、つぎのコードを考えてみてください:</p>

<pre class="php"><span class="kw2">&lt;?php</span>
    <span class="re0">$card_list</span> <span class="sy0">=</span> <span class="kw3">array</span><span class="br0">&#40;</span>
      <span class="st_h">'VISA'</span> <span class="sy0">=&gt;</span> <span class="st_h">'Visa'</span><span class="sy0">,</span>
      <span class="st_h">'MAST'</span> <span class="sy0">=&gt;</span> <span class="st_h">'MasterCard'</span><span class="sy0">,</span>
      <span class="st_h">'AMEX'</span> <span class="sy0">=&gt;</span> <span class="st_h">'American Express'</span><span class="sy0">,</span>
      <span class="st_h">'DISC'</span> <span class="sy0">=&gt;</span> <span class="st_h">'Discover'</span><span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="kw1">echo</span> select_tag<span class="br0">&#40;</span><span class="st_h">'cc_type'</span><span class="sy0">,</span> options_for_select<span class="br0">&#40;</span><span class="re0">$card_list</span><span class="sy0">,</span> <span class="st_h">'AMEX'</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="sy1">?&gt;</span></pre>
  
  <p>これはつぎのHTMLを出力します:</p>

<pre class="php"><span class="sy0">&lt;</span>select name<span class="sy0">=</span><span class="st0">&quot;cc_type&quot;</span> id<span class="sy0">=</span><span class="st0">&quot;cc_type&quot;</span><span class="sy0">&gt;</span>
  <span class="sy0">&lt;</span>option value<span class="sy0">=</span><span class="st0">&quot;VISA&quot;</span><span class="sy0">&gt;</span>Visa<span class="sy0">&lt;/</span>option<span class="sy0">&gt;</span>
  <span class="sy0">&lt;</span>option value<span class="sy0">=</span><span class="st0">&quot;MAST&quot;</span><span class="sy0">&gt;</span>MasterCard<span class="sy0">&lt;/</span>option<span class="sy0">&gt;</span>
  <span class="sy0">&lt;</span>option value<span class="sy0">=</span><span class="st0">&quot;AMEX&quot;</span> selected<span class="sy0">=</span><span class="st0">&quot;selected&quot;</span><span class="sy0">&gt;</span>American Express<span class="sy0">&lt;/</span>option<span class="sy0">&gt;</span>
  <span class="sy0">&lt;</span>option value<span class="sy0">=</span><span class="st0">&quot;DISC&quot;</span><span class="sy0">&gt;</span>Discover<span class="sy0">&lt;/</span>option<span class="sy0">&gt;</span>
<span class="sy0">&lt;/</span>select<span class="sy0">&gt;</span></pre>
  
  <p>テンプレートのなかでヘルパーを利用する利点はコードを書く時間の理論値、コードの明瞭性と簡潔性です。支払う唯一の代償は学習時間と<code>&lt;?php echo ?&gt;</code>を書く時間です。学習の方はこの本を読み終わるまでに終わり、<code>&lt;?php echo ?&gt;</code>を書く作業は好きなテキストエディタでショートカットを用意すればすみます。テンプレート内でsymfonyのヘルパーを使わずに従来の方法でHTMLを書くことはできますが、その方法では多くの時間が失われ面白くなくなります。</p>
</blockquote>

<p>短縮型の開始タグ(<code>&lt;?=</code>は<code>&lt;?php echo</code>と同じ)の使用はプロフェッショナルなWebアプリケーションに対して非推奨であることに注意してください。運用のWebサーバーは複数のスクリプト言語を理解できるので結果として混乱する可能性があるからです。加えて短縮型の開始タグはPHPのデフォルトの設定では機能せず、有効にするためにサーバーを調整する必要があるからです(訳注：short_open_tagディレクティブをonに設定する)。結局のところ、XMLとバリデーションを処理しなければならないとき、XMLにおいて<code>&lt;?</code>は特別な意味を持つので不十分な表記です。</p>

<p>フォームの操作を説明するにはまるごと1章必要です。symfonyはフォームの操作を簡単にするために、多くのツール、大部分はヘルパーですが、を提供します。これらのヘルパーは10章で学ぶことになります。</p>

<a name="linking.to.another.action" id="linking.to.another.action"></a><h2>別のアクションにリンクする</h2>

<p>アクションの名前とそれを呼び出すURLが完全に分離されていることはご存じのとおりです。ですのでリスト4-10のようにテンプレートのなかで<code>anotherAction</code>アクションへのリンクを作る場合、リンクはデフォルトのルーティングのみで動作します。URLの表示方法の変更をあとで決める場合、ハイパーリンクを変更するにはすべてのテンプレートを再吟味する必要があります。</p>

<p>リスト4-10 - 古典的な方法による、ハイパーリンク</p>

<pre class="php"><span class="sy0">&lt;</span>a href<span class="sy0">=</span><span class="st0">&quot;/myapp_dev.php/mymodule/anotherAction?name=anonymous&quot;</span><span class="sy0">&gt;</span>
  私の名前は教えません
<span class="sy0">&lt;/</span>a<span class="sy0">&gt;</span></pre>

<p>このやっかいな問題を避けるには、アプリケーションのアクションへのハイパーリンクを作る<code>link_to</code>ヘルパーをつねに使うべきです。リスト4-11はハイパーリンクのヘルパーの使いかたを示しています。</p>

<p>リスト4-11 - <code>link_to()</code>ヘルパー(<code>templates/***Success.php</code>)</p>

<pre class="php">&lt;p&gt;こんにちは！&lt;/p&gt;
<span class="kw2">&lt;?php</span> <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$hour</span> <span class="sy0">&gt;=</span> <span class="nu0">18</span><span class="br0">&#41;</span><span class="sy0">:</span> <span class="sy1">?&gt;</span>
&lt;p&gt;もしくはこんばんはと言ったほうがよろしいでしょうか？もう<span class="kw2">&lt;?php</span> <span class="kw1">echo</span> <span class="re0">$hour</span> <span class="sy1">?&gt;</span>時です。&lt;/p&gt;
<span class="kw2">&lt;?php</span> <span class="kw1">endif</span><span class="sy0">;</span> <span class="sy1">?&gt;</span>
<span class="kw2">&lt;?php</span> <span class="kw1">echo</span> form_tag<span class="br0">&#40;</span><span class="st_h">'mymodule/anotherAction'</span><span class="br0">&#41;</span> <span class="sy1">?&gt;</span>
  <span class="kw2">&lt;?php</span> <span class="kw1">echo</span> label_for<span class="br0">&#40;</span><span class="st_h">'name'</span><span class="sy0">,</span> <span class="st_h">'お名前は？'</span><span class="br0">&#41;</span> <span class="sy1">?&gt;</span>
  <span class="kw2">&lt;?php</span> <span class="kw1">echo</span> input_tag<span class="br0">&#40;</span><span class="st_h">'name'</span><span class="br0">&#41;</span> <span class="sy1">?&gt;</span>
  <span class="kw2">&lt;?php</span> <span class="kw1">echo</span> submit_tag<span class="br0">&#40;</span><span class="st_h">'Ok'</span><span class="br0">&#41;</span> <span class="sy1">?&gt;</span>
  <span class="kw2">&lt;?php</span> <span class="kw1">echo</span> link_to<span class="br0">&#40;</span><span class="st_h">'名前を教えない'</span><span class="sy0">,</span><span class="st_h">'mymodule/anotherAction?name=anonymous'</span><span class="br0">&#41;</span> <span class="sy1">?&gt;</span>
&lt;/form&gt;</pre>

<p>ルーティングルールを変更するとき、すべてのテンプレートが正しくふるまいURLをルールにしたがって再び整形すること以外、結果のHTMLは以前のものと同じになります。</p>

<p><code>link_to()</code>ヘルパーは、多くのヘルパーと同じように、特別なオプションと追加のタグ属性のために別の引数を受けとります。リスト4-12はオプション引数の例と結果のHTMLを示します。オプション引数は連想配列もしくは空白によって区切られた<code>key=value</code>の組を表示するシンプルな文字列です。</p>

<p>リスト4-12 - たいていのヘルパーはオプション引数を受けとる(<code>templates/***Success.php</code>)</p>

<pre class="php">// 連想配列としてのオプション引数
<span class="kw2">&lt;?php</span> <span class="kw1">echo</span> link_to<span class="br0">&#40;</span><span class="st_h">'名前を教えない'</span><span class="sy0">,</span> <span class="st_h">'mymodule/anotherAction?name=anonymous'</span><span class="sy0">,</span>
  <span class="kw3">array</span><span class="br0">&#40;</span>
    <span class="st_h">'class'</span>    <span class="sy0">=&gt;</span> <span class="st_h">'special_link'</span><span class="sy0">,</span>
    <span class="st_h">'confirm'</span>  <span class="sy0">=&gt;</span> <span class="st_h">'よろしいですか？'</span><span class="sy0">,</span>
    <span class="st_h">'absolute'</span> <span class="sy0">=&gt;</span> <span class="kw4">true</span>
<span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="sy1">?&gt;</span>
&nbsp;
// 文字列としてのオプション引数
<span class="kw2">&lt;?php</span> <span class="kw1">echo</span> link_to<span class="br0">&#40;</span><span class="st_h">'名前を教えない'</span><span class="sy0">,</span> <span class="st_h">'mymodule/anotherAction?name=anonymous'</span><span class="sy0">,</span>
  <span class="st_h">'class=special_link confirm=Are you sure? absolute=true'</span><span class="br0">&#41;</span> <span class="sy1">?&gt;</span>
&nbsp;
// 両方の呼び出しは同じものを出力する
 =&gt; &lt;a class=&quot;special_link&quot; onclick=&quot;return confirm('Are you sure?');&quot;
    href=&quot;http://localhost/myapp_dev.php/mymodule/anotherAction/name/anonymous&quot;&gt;
    名前を教えない&lt;/a&gt;</pre>

<p>HTMLタグを出力するsymfonyのヘルパーを使うとき、オプション引数に(リスト4-12の例の<code>class</code>属性のような)追加のタグ属性を挿入できます。これらの属性を"速くて汚い"HTML 4.0の方法(ダブルクォートなし)で書くこともできますが、symfonyはすばらしく整形されたXHTMLでそれらを出力します。それがヘルパーがHTMLを書くより速い別の理由です。</p>

<blockquote class="note"><p>
  追加の解析と変換が必要なので、文字列の構文は配列よりも若干遅いです。</p>
</blockquote>

<p>フォームヘルパーのように、リンクヘルパーとオプションは数多く存在します。9章でこれらを詳しく説明します。</p>

<a name="getting.information.from.the.request" id="getting.information.from.the.request"></a><h2>リクエストから情報を入手する</h2>

<p>ユーザーが送信した情報がフォーム経由(通常はPOSTリクエスト)もしくはURL経由(GETリクエスト)のどちらでも、<code>sfActions</code>オブジェクトの<code>getRequestParameter()</code>メソッドを用いてアクションから関連するデータをとり出すことができます。リスト4-13は、<code>anotherAction</code>メソッドで、<code>name</code>パラメーターの値をとり出す方法を示しています。</p>

<p>リスト4-13 - データをアクションのリクエストパラメーターから取得する(<code>mymodule/actions/actions.class.php</code>)</p>

<pre class="php"><span class="kw2">&lt;?php</span>
&nbsp;
<span class="kw2">class</span> mymoduleActions <span class="kw2">extends</span> sfActions
<span class="br0">&#123;</span>
  <span class="sy0">...</span>
&nbsp;
  <span class="kw2">public</span> <span class="kw2">function</span> executeAnotherAction<span class="br0">&#40;</span><span class="br0">&#41;</span>
  <span class="br0">&#123;</span>
    <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">name</span> <span class="sy0">=</span> <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">getRequestParameter</span><span class="br0">&#40;</span><span class="st_h">'name'</span><span class="br0">&#41;</span><span class="sy0">;</span>
  <span class="br0">&#125;</span>
<span class="br0">&#125;</span></pre>

<p>データの操作方法がシンプルであるなら、リクエストパラメーターをとり出すためにアクションを使う必要もありません。テンプレートが<code>$sf_params</code>という名前のオブジェクトにアクセスできるからです。アクションの<code>getRequestParameter()</code>と同様に、<code>$sf_params</code>はリクエストパラメーターをとり出す<code>get()</code>メソッドを提供します。</p>

<p><code>executeAnotherAction()</code>が空の場合、リスト4-14は<code>anotherActionSuccess.php</code>テンプレートが同じ<code>name</code>パラメーターをとり出す方法を示しています。</p>

<p>リスト4-14 - リクエストパラメーターをテンプレートから直接取得する(<code>templates/***Success.php</code>)</p>

<pre class="php">&lt;p&gt;Hello, <span class="kw2">&lt;?php</span> <span class="kw1">echo</span> <span class="re0">$sf_params</span><span class="sy0">-&gt;</span><span class="me1">get</span><span class="br0">&#40;</span><span class="st_h">'name'</span><span class="br0">&#41;</span> <span class="sy1">?&gt;</span>!&lt;/p&gt;</pre>

<blockquote class="note"><p>
  なぜ、代わりに<code>$_POST</code>、<code>$_GET</code>、<code>$_REQUEST</code>変数を使わないのでしょうか？なぜならURLは異なるようにフォーマットされるため(たとえば<code>?</code>や<code>=</code>をともなわない<code>http://localhost/articles/europe/france/finance.html</code>)、通常のPHP変数はそれ以上機能しないので、ルーティングシステムのみがリクエストパラメーターをとり出すことができるからです。悪意のあるコードのインジェクションを防止するために、入力フィルタリングを追加したい場合、これはすべてのリクエストパラメーターを1つのクリーンなパラメーターホルダーに保持する場合のみ実現できます。</p>
</blockquote>

<p><code>$sf_params</code>オブジェクトは単に同等のゲッターを配列に渡すよりも強力です。たとえば、リクエストパラメーターの存在を確認することだけを試したい場合、リスト4-15のように、実際の値を<code>get()</code>で試す代わりに<code>$sf_params-&gt;has()</code>メソッドで簡単に利用できます。</p>

<p>リスト4-15 - テンプレートのなかでリクエストパラメーターを試す(<code>templates/***Success.php</code>)</p>

<pre class="php"><span class="kw2">&lt;?php</span> <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$sf_params</span><span class="sy0">-&gt;</span><span class="me1">has</span><span class="br0">&#40;</span><span class="st_h">'name'</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">:</span> <span class="sy1">?&gt;</span>
  &lt;p&gt;こんにちは、<span class="kw2">&lt;?php</span> <span class="kw1">echo</span> <span class="re0">$sf_params</span><span class="sy0">-&gt;</span><span class="me1">get</span><span class="br0">&#40;</span><span class="st_h">'name'</span><span class="br0">&#41;</span> <span class="sy1">?&gt;</span>さん！&lt;/p&gt;
<span class="kw2">&lt;?php</span> <span class="kw1">else</span><span class="sy0">:</span> <span class="sy1">?&gt;</span>
  &lt;p&gt;こんにちは、John Doeさん！&lt;/p&gt;
<span class="kw2">&lt;?php</span> <span class="kw1">endif</span><span class="sy0">;</span> <span class="sy1">?&gt;</span></pre>

<p>読者のなかにはこれを一行で書けることをすでに推測している人がいるでしょう。symfonyのたいていのゲッターメソッドに関しては、アクションの<code>getRequestParameter()</code>メソッドとテンプレートの<code>$sf_params-&gt;get()</code>メソッド(実際には、同じオブジェクトの同じメソッドの呼び出し)の両方とも2番目の引数としてリクエストパラメーターが存在しない場合に使われるデフォルト値を受けとります。</p>

<pre class="php">&lt;p&gt;こんにちは、<span class="kw2">&lt;?php</span> <span class="kw1">echo</span> <span class="re0">$sf_params</span><span class="sy0">-&gt;</span><span class="me1">get</span><span class="br0">&#40;</span><span class="st_h">'name'</span><span class="sy0">,</span> <span class="st_h">'John Doe'</span><span class="br0">&#41;</span> <span class="sy1">?&gt;</span>さん！&lt;/p&gt;</pre>

<a name="summary" id="summary"></a><h2>まとめ</h2>

<p>symfonyにおいて、ページはアクションとテンプレートで構成されます。アクションは<code>actions/actions.class.php</code>ファイルのメソッドでプレフィックスが<code>execute</code>で、テンプレートは<code>templates/</code>ディレクトリ内のファイルで、通常は<code>Success.php</code>で終わります。これらはアプリケーション内の機能にしたがって、モジュールに分類されます。ヘルパーによってテンプレートを円滑に書けます。ヘルパー(helper)とはsymfonyによって提供されるHTMLコードを返す関数です。そして、必要に応じて整形されるURLはレスポンスの一部として考えることが必要です。ですのでアクションの命名もしくはリクエストパラメーターの読みとりにおいてURLを直接参照することは避けるべきです。</p>

<p>これらの基本的な原則を理解したら、すでにアプリケーション全体を書けます。しかしながらこれだけでは作業が長すぎます。アプリケーションの開発過程の間に実現しなければならないほとんどすべてのタスクは別のsymfonyの機能によって1つもしくは別の方法で円滑になります・・・今のところこの本が終わらない理由です。</p>
</div>
<div class="navigation">
<hr/>
<table width="100%">
<tr>
<td width="40%" align="left"><a href="03-Running-Symfony.html">前の章</a></td>
<td width="20%" align="center"><a href="index.html">ホーム</a></td>
<td width="40%" align="right"><a href="05-Configuring-Symfony.html">次の章</a></td>
</tr>
</table>

</div>
</body>

</html>
